<template>
  <a-spin :spinning="isLoading">
    <div style="display: flex; align-items: center">
      <div
        class="top_left"
        style="margin-right: 30px; display: flex; align-items: center"
      >
        <a-button
          @click="addupdates"
          style="border-radius: 5px"
          :disabled="!isAnyChecked"
          v-if="isvideoGroup"
          >导入视频组</a-button
        >

        <div style="margin-left: 20px" v-if="upload_ing_ing">
          上传至
          <span style="color: red; font-weight: 700">{{ mater_name }}</span>
          文件夹中
          <loading-outlined style="margin-left: 5px" />
        </div>

        <div style="margin-left: 20px" v-if="upload_finish_finish">
          成功上传至
          <span style="color: red; font-weight: 700">{{ mater_name }}</span>
          文件夹中!
        </div>
      </div>
    </div>

    <div class="folder_list">
      <div class="custom_upload" v-if="!noupload">
        <div class="upload_top" @click="newSubFolder">
          <FolderAddOutlined style="font-size: 16px; margin-right: 2px" />
          <div>新建文件夹</div>
        </div>

        <div class="upload_mater">
          <a-upload
            class="model_upload"
            v-model:file-list="fileList"
            :before-upload="beforeUpload"
            :multiple="true"
            name="file"
            :accept="getAcceptValue"
            :customRequest="customRequest"
            :disabled="update_ing || noenzu"
            style="width: 100%; height: 50%; background-color: #000"
          >
            <div class="model_upload_text">
              <cloud-upload-outlined style="margin-right: 2px" />
              上传素材
            </div>
            <template #itemRender="{ file, actions }"> </template>
          </a-upload>
        </div>
      </div>

      <div class="noupload_custom_upload" v-if="noupload">
        <div class="upload_top" @click="newSubFolder">
          <FolderAddOutlined style="font-size: 16px; margin-right: 2px" />
          <div>新建文件夹</div>
        </div>
      </div>

      <div
        class="folder_item"
        v-for="(item, index) in list"
        :key="index"
        :style="{ paddingRight: '5px' }"
      >
        <div :class="{ mask: shouldShowMask(index) }"></div>
        <a-checkbox
          v-if="isvideoGroup"
          class="folder_list_checkbox"
          v-model:checked="item.checked"
        ></a-checkbox>
        <div
          class="count"
          v-if="item.statck_multimedias_count || item.statck_texts_count"
        >
          {{ item.statck_multimedias_count || item.statck_texts_count }}
        </div>
        <div class="folder_icon" @click="chooseFolder(item, index)">
          <cu-icon
            class="icon"
            type="icon-wenjianjia1"
            style="font-size: 82px; cursor: pointer; margin-left: 17px"
          />
          <cu-icon
            class="icon icon-postion"
            type="icon-tupian1"
            v-if="item.folder_type == 'image'"
          />
          <cu-icon
            class="icon icon-postion"
            type="icon-yuyin"
            v-if="item.folder_type == 'audio'"
          />
          <cu-icon
            class="icon icon-postion"
            type="icon-zhinengwenan"
            v-if="item.folder_type == 'text'"
          />
          <cu-icon
            class="icon icon-postion"
            type="icon-shipin"
            v-if="item.folder_type == 'video'"
          />
        </div>
        <div class="folder_name">{{ item.folder_name }}</div>
      </div>
    </div>
  </a-spin>
</template>

<script>
import {
  defineComponent,
  reactive,
  toRefs,
  computed,
  watch,
  toRaw,
  createVNode,
  ref,
  nextTick,
  h,
} from "vue";
import request from "../../../../../../common/utils/request";
import defaultSetting from "@/common/utils/defaultSetting.js";
import { upload } from "@/common/utils/uploader/index";
import store from "../../../../../../store";
import axios from "axios";
import { cancelUpload } from "@/common/utils/uploader/drivers/oss.js";
import utils from "@/common/utils/utils.js";
import {accept}from '@/common/utils/atherUtils.js'

import {
  FolderOutlined,
  FolderAddOutlined,
  CloseCircleOutlined,
  CloudUploadOutlined,
  LoadingOutlined,
} from "@ant-design/icons-vue";
import { message, notification } from "ant-design-vue";
export default defineComponent({
  props: {
    list: {
      type: Array,
      default: () => {
        return [];
      },
    },
    isLoading: {
      type: Boolean,
      default: false,
    },
    // 混剪的 镜头组来的  特殊处理
    isvideoGroup: {
      type: Boolean,
      default: false,
    },
    extension: {
      type: String,
      default: "",
    },
    material_type: {
      type: String,
      default: "",
    },
    NewMemory: {
      type: Object,
      default: {},
    },
    istongyong: {
      type: Boolean,
      default: false,
    },
    noupload: {
      type: Boolean,
      default: false,
    },
  },
  components: {
    FolderAddOutlined,
    CloseCircleOutlined,
    CloudUploadOutlined,
    LoadingOutlined,
  },
  setup(props, context) {
    const state = reactive({
      updatedList: [],
      filteredItems: [],
      ischecked: false,
      fileList: [],
      queryData: {
        files: [],
      },
      BASE_URL: "",
      oss_config_Info: {},
      SetUploadPath: "",
      fileMaxSize: "",
      free_send_text: "",
      fileMaxSizeErr: "",

      All_file: [],
      iscount: 0,
      isAll_upload: true,
      Success_list: [],
      image_id: "",
      video_id: "",
      audio_id: "",
      uploading_list: [],
      notCompletedCount: 0,
      ALLshouldContinuePolling: true,
      cos_progressList: [],
      update_ing: false,
      mater_name: "",
      upload_ing_ing: false,
      upload_finish_finish: false,
      noenzu: false,
    });

    // 上传的类型
    const getAcceptValue = computed(() => {
      switch (props.material_type) {
        case "video":
          return accept.videoAccept;
        case "image":
          return accept.imageAccept;
        case "audio":
          return accept.audioAccept;
        default:
          return `${accept.videoAccept},${accept.imageAccept},${accept.audioAccept}`;
          // return ".mp4,.mov,.3gp,.jpg,.jpeg,.png,.mp3,.m4a,.aac,.wav";
      }
    });

    const work_ai_config = computed(() => {
      return store?.state?.shotstack?.work_ai_config || {};
    });

    const isAlionline = computed(() => {
      return work_ai_config.value?.shotstack_driver == "alionline";
    });

    const isOss = computed(() => {
      return work_ai_config.value?.upload_driver == "oss";
    });

    const chooseFolder = (item, index) => {
      context.emit("choose", item);
    };

    const newSubFolder = () => {
      context.emit("newFolder");
    };

    const shouldShowMask = (index) => {
      return props.list.some((item, i) => i !== index && item.checked);
    };

    // 导入视频组
    const addupdates = () => {
      state.filteredItems = props.list.filter((item) => item.checked === true);
      if (state.filteredItems.length > 0) {
        getMediaList(state.filteredItems[0]);
      } else {
        message.error("请选择文件夹 !");
      }
    };

    const isAnyChecked = computed(() => {
      return props.list.some((item) => item.checked);
    });

    // 获取文件夹内的 内容
    const getMediaList = (params) => {
      let queryData = {
        merchant_folder_statck_id: params.id,
        multimedia_tag_id: "",
        pageSize: 50,
        page: 0,
      };

      request
        .post("/work_ai", "/user/shotstack/media/list", queryData)
        .then((res) => {
          const videoDate = res.result.data;
          context.emit("getChoose", videoDate);
        });
    };

    // 上传前的准备
    const beforeUpload = async (file, fileList) => {
      state.queryData.files = fileList;
      const typeParts = file.type.split("/");
      const mimeType = typeParts[0];
      createFloder(mimeType);

      switch (mimeType) {
        case "video":
          return new Promise((resolve) => {
            const isLt1G = file.size / 1024 / 1024 / 1024 < 1;
            if (!isLt1G) {
              message.error("视频文件不可大于 1GB!");
              resolve(false);
              return;
            }
            const video = document.createElement("video");
            const blobURL = URL.createObjectURL(file);
            video.src = blobURL;
            video.onloadedmetadata = () => {
              const duration = video.duration;
              const width = video.videoWidth;
              const height = video.videoHeight;

              if (duration > 3600) {
                message.error("视频文件不能大于 60 分钟时长!");
                resolve(false);
                return;
              }

              if (width > 4096 || height > 4096) {
                message.error("视频最大不能超过 4096px!");
                resolve(false);
                return;
              }

              resolve(true);
            };
          });
        case "image":
          const isLt2M = file.size / 1024 / 1024 < 20;
          let w = 0,
            h = 0;
          let reader = new FileReader();
          reader.readAsDataURL(file);
          reader.onload = () => {
            const image = new Image();
            image.src = reader.result;
            image.onload = () => {
              w = image.width;
              h = image.height;
              if (w <= 49 || h <= 49) {
                state.fileList = state.fileList.filter(
                  (item) => item.uid !== file.uid
                );
                message.error("图片宽度不能小于50px");
                return false;
              } else if (w >= 8000 || h >= 8000) {
                state.fileList = state.fileList.filter(
                  (item) => item.uid !== file.uid
                );
                message.error("图片宽度不能大于8000px");
                return false;
              }
              if (!isLt2M) {
                message.error("文件不可大于 20M!");
                return false;
              }
              return true;
            };
          };
        default:
      }
    };

    //  手动上传
    const customRequest = () => {
      state.iscount += 1;
      if (state.iscount !== state.queryData.files.length) return;
      state.update_ing = true;
      // ----------------------cos----------------------------
      const uploadQueue = [];
      const MAX_CONCURRENT_UPLOADS = 2;

      state.BASE_URL = defaultSetting.requestDomain;
      if (process.env.NODE_ENV === "development") {
        state.BASE_URL = state.BASE_URL + "/api";
      }

      // 检查剩余空间并上传文件
      function uploadFile(file, index) {
        return new Promise((resolve, reject) => {
          request
            .post("/work_ai", "/material/get/capacity")
            .then((res) => {
              const remainingCapacity = parseInt(res.result.remainingCapacity, 10);
              const typeParts = file.type.split("/");
              const mimeType = typeParts[0];
              if (remainingCapacity < file.size) {
                message.error(`存储空间不足，无法上传文件：${file.name}`);
                resolve();
              } else {
                const formData = new FormData();
                formData.append("file", file);
                formData.append("type", mimeType);
                formData.append("scene", mimeType);
                formData.append(
                  "merchant_folder_statck_id",
                  mimeType == "image"
                    ? state.image_id
                    : mimeType == "video"
                    ? state.video_id
                    : mimeType == "audio"
                    ? state.audio_id
                    : null
                );
                formData.append("org_id", utils.getOrgId());
                formData.append("user_token", utils.getToken());
                formData.append(
                  "cur_env",
                  utils.isMobile()
                    ? "h5"
                    : import.meta.env.ELECTRON
                    ? "desktop"
                    : "pc"
                );
                formData.append("team_id", utils.getCurrentTeam());
                formData.append("path_synchronous", "1");
                axios({
                  method: "post",
                  url: `${state.BASE_URL}/work_ai/material/upload`,
                  data: formData,
                  headers: {
                    "Content-Type": "multipart/form-data",
                    "Org-Token": utils.getToken(),
                  },
                })
                  .then((response) => {
                    if (response?.data?.data?.errorData.length > 0) {
                      // 错误处理
                      notification.warn({
                        message: response.data.data.errorData[0],
                        duration: 2,
                      });
                      resolve();
                    } else {
                      handleUploadSuccess(response, index)
                        .then(resolve)
                        .catch(reject);
                    }
                  })
                  .catch(reject);
              }
            })
            .catch(reject);
        });
      }

      // 处理上传成功的逻辑
      async function handleUploadSuccess(response, index) {
        state.cos_progressList[index].is_uping = true;

        let pollInterval;
        let shouldContinuePolling = true;

        pollInterval = setInterval(async () => {
          if (!state.ALLshouldContinuePolling) {
            clearInterval(pollInterval);
            return;
          }
          if (!shouldContinuePolling) {
            clearInterval(pollInterval);
            return;
          }

          await request
            .get("/work_ai", "/material/upload/status", {
              taskId: response?.data?.data?.returnData[0]?.taskId,
            })
            .then(async (res) => {
              if (res.status === 1) {
              } else if (res.status === 2) {
                shouldContinuePolling = false;
                clearInterval(pollInterval);
                await markUploadComplete(index);
              } else if (res.status === 3) {
                // 上传失败  停止轮训
                shouldContinuePolling = false;
                message.error("上传失败");
                clearInterval(pollInterval);
              }
            })
            .catch((error) => {
              clearInterval(pollInterval);
            });
        }, 2000);

        return new Promise((resolve) => {
          setTimeout(resolve, 5000);
        });
      }

      // 标记上传完成  (cos 进度相关)
      async function markUploadComplete(index) {
        state.cos_progressList[index].is_uping = false;
        state.cos_progressList[index].is_upfinish = true;

        store.dispatch("SetCosProgresslist", state.cos_progressList);
        const allUploadsFinished = state.markUploadComplete.every(
          (item) => item.is_upfinish
        );
        if (allUploadsFinished) {
          state.update_ing = true;
          message.success("上传成功!");
        }
      }

      // Cos上传
      async function startUploads() {
        // 增加进度条 状态值
        state.cos_progressList = state.queryData.files.map((item) => {
          return {
            ...item,
            is_uping: false,
            is_upfinish: false,
            name: item.name,
          };
        });

        // cos 开始上传
        store.dispatch("SetCosProgresslist", state.cos_progressList);
        for (let i = 0; i < state.queryData.files.length; i++) {
          const file = state.queryData.files[i];
          uploadQueue.push(uploadFile(file, i));
          if (uploadQueue.length > MAX_CONCURRENT_UPLOADS) {
            await uploadQueue.shift();
          }
        }
        await Promise.all(uploadQueue);
      }

      // ----------------oss--------------------------

      // 控制并发数量的函数
      async function processQueue(queue, concurrency) {
        const runningTasks = new Set();
        const results = [];

        const addTask = async () => {
          if (queue.length === 0) {
            return;
          }

          const task = queue.shift();
          const promise = task()
            .then((res) => {
              if (res == undefined) {
                res = false;
              }
              results.push(res);
              runningTasks.delete(promise);
              addTask();
            })
            .catch((error) => {
              results.push(null);
              runningTasks.delete(promise);
              addTask();
            });
          runningTasks.add(promise);
        };

        // 初始填充运行任务
        for (let i = 0; i < concurrency; i++) {
          addTask();
        }
        // 等待所有任务完成
        while (runningTasks.size > 0 || queue.length > 0) {
          await Promise.race(runningTasks);
        }

        return results;
      }

      let oss_config;
      let refreshTimeout;
      async function getOss_config() {
        const response = await request.post(
          "/work_ai",
          "/upload/oss/config/ststoken",
          {
            isRefresh: "1",
          }
        );
        if (response.sts) {
          oss_config = response.sts;
          const duration = response.sts.duration;
          const refreshTime = (duration - 5 * 60) * 1000;
          refreshTimeout = setTimeout(getOss_config, refreshTime);
          const nowTimestamp = Date.now();
          const expiresAtTimestamp =
            nowTimestamp + response.sts.duration * 1000;
          const stsToken_config = {
            stsToken: response.sts.stsToken,
            duration: response.sts.duration,
            FailDate: expiresAtTimestamp,
          };

          localStorage.setItem(
            "stsToken_config",
            JSON.stringify(stsToken_config)
          );
        } else {
          const Reres = await request.post(
            "/work_ai",
            "/upload/oss/config/ststoken",
            {
              isRefresh: "1",
            }
          );
          oss_config = Reres.sts;
          const duration = Reres.sts.duration;
          const refreshTime = (duration - 5 * 60) * 1000;
          refreshTimeout = setTimeout(getOss_config, refreshTime);
        }
      }

      // Oss上传
      async function startOssUploads() {
        await getOss_config();

        let upDataList = state.queryData.files.map((item) => ({
          ...item,
          name: item.name,
          id: item.uid,
          state: 0,
          percent: 0,
          iscancel: false,
        }));

        // 将上传数据 同步至vuex
        store.dispatch("SetUpDateList", upDataList);
        state.upload_finish_finish = false;
        state.upload_ing_ing = true;

        const uploadQueue = state.queryData.files.map((file, i) => async () => {
          // 可选的配置对象
          const config = {
            SetUploadPath: state.SetUploadPath,
            oss_config: oss_config,
          };

          const res = await upload(file, config);
          state.Success_list.push(res);

          const typeParts = file.type.split("/");
          const mimeType = typeParts[0];

          let up_paramas = {
            merchant_folder_statck_id:
              mimeType == "image"
                ? state.image_id
                : mimeType == "video"
                ? state.video_id
                : mimeType == "audio"
                ? state.audio_id
                : null,
            material_type: mimeType,
            material_name: file.name,
            material_url: res.fileUrl,
            material_size: file.size,
          };

          try {
            const response = await request.post(
              "/work_ai",
              "/user/mobile/media",
              up_paramas
            );
            return response;
          } catch (error) {
            isclose();
            state.update_ing = false;
            message.error("上传失败!");
          }
        });
        

        const results = await processQueue(uploadQueue, 2);
        if (results.every((res) => res?.result) && state.isAll_upload) {
          context.emit("uploadSuccess", props.NewMemory);
          state.upload_ing_ing = false;
          state.upload_finish_finish = true;

          state.update_ing = false;
        }
      }

      async function remove_fail(index) {}

      // 判断驱动
      if (isAlionline.value || isOss.value) {
        // oss上传
        startOssUploads();
      } else {
        startUploads();
      }
    };

    const onClose = () => {};

    // 阿里直传相关
    const getaliinfo = async (id) => {
      await request
        .get("/work_ai", "/material/upload/info", {
          merchant_folder_statck_id: id,
          upload_from: "",
          number:1
        })
        .then((res) => {
          if (res.code == 1001) {
            state.noenzu = true;
          }
          if (res.result) {
            state.SetUploadPath = res.result.upload_path;
            state.fileMaxSize = res.result.fileMaxSize;
            state.free_send_text = res.result.free_send_text;
            state.fileMaxSizeErr = res.result.fileMaxSizeErr;
          }
        });
    };

    const createFloder = async (mimeType) => {
      let params = {
        merchant_library_id: props.istongyong
          ? 0
          : props.NewMemory.merchant_library_id,
        group_id: props.NewMemory.group_id,
        upload_file_type: [mimeType],
        merchant_type: props.istongyong ? 0 : 1,
      };
      await request
        .post("/work_ai", "/user/shotstack/folder/type/create", params)
        .then((res) => {
          let id;
          if (res.result.video) {
            id = res.result.video;
            state.video_id = res.result.video;
            if (!state.mater_name.includes("视频")) {
              if (state.mater_name !== "") {
                state.mater_name += " / ";
              }
              state.mater_name += "视频";
            }
          }
          if (res.result.image) {
            id = res.result.image;
            state.image_id = res.result.image;
            if (!state.mater_name.includes("图片")) {
              if (state.mater_name !== "") {
                state.mater_name += " / ";
              }
              state.mater_name += "图片";
            }
          }
          if (res.result.audio) {
            id = res.result.audio;
            state.audio_id = res.result.audio;

            if (!state.mater_name.includes("音频")) {
              if (state.mater_name !== "") {
                state.mater_name += " / ";
              }
              state.mater_name += "音频";
            }
          }

          getaliinfo(id);
        });
    };

    const closeFn = async (index) => {
      await cancelUpload(state.uploading_list[index].id);
      state.uploading_list[index].iscancel = true;
      state.uploading_list.splice(index, 1);
      await store.dispatch("SetDelUpData", state.uploading_list);
    };

    return {
      ...toRefs(state),
      onClose,
      getMediaList,
      addupdates,
      chooseFolder,
      newSubFolder,
      shouldShowMask,
      isAnyChecked,
      getAcceptValue,
      beforeUpload,
      customRequest,
      work_ai_config,
      isAlionline,
      isOss,
      getaliinfo,
      createFloder,
      closeFn,
    };
  },
});
</script>

<style lang="less" scoped>
.no_data {
  color: 14px;
  width: 100%;
  height: 300px;
  display: flex;
  align-items: center;
  justify-content: center;
  color: #fff;
}

.folder_list {
  display: flex;
  align-items: center;
  flex-wrap: wrap;
  align-content: flex-start;
  width: 100%;
  height: calc(500px - 62px);
  overflow-y: auto;

  &::-webkit-scrollbar {
    display: none;
  }

  .custom_upload {
    width: 110px;
    height: 130px;
    border-radius: 10px;
    background: #f9f9f9 !important;
    border: 1px dashed #ddd;
    display: flex;
    flex-direction: column;
    justify-content: space-evenly;
    cursor: pointer;
    margin-left: 10px;
    margin-top: 20px;
    padding: 3px;
    .upload_top {
      height: 50%;
      width: 100%;
      display: flex;
      // font-weight: 700;
      align-items: center;
      justify-content: center;
      border-bottom: 1px dashed #ccc;
      padding-bottom: 10px;
      // color: #696969;

      &:hover {
        color: #fff !important;
        background-color: #73cff8 !important;
        border-radius: 5px;
      }
    }

    .upload_mater {
      width: 100%;
      height: 50%;
      color: #696969;

      :hover {
        color: #fff !important;
        background-color: #73cff8;
        border-radius: 5px;
      }
    }
  }

  .folder_item {
    cursor: pointer;
    flex-shrink: 0;
    width: 110px;
    height: 126px;
    color: #fff;
    display: flex;
    flex-direction: column;
    align-items: center;
    justify-content: center;
    margin-top: 20px;
    margin-left: 10px;
    position: relative;
    padding-right: 8px;

    .folder_list_checkbox {
      position: absolute;
      top: 8px;
      left: 10px;
    }

    &:hover {
      background-color: rgba(0, 0, 0, 0.1);
      border-radius: 10px;
    }

    .count {
      position: absolute;
      height: 20px;
      min-width: 20px;
      border-radius: 50px;
      border: 1px solid #fff;
      display: flex;
      align-items: center;
      justify-content: center;
      color: #fff;
      background-color: rgba(0, 0, 0, 0.3);
      right: 8px;
      top: 12px;
      font-size: 14px;
      text-align: center;
      line-height: 18px;
      z-index: 999;
    }

    .folder_icon {
      font-size: 25px;
      position: relative;
      display: flex;
      align-items: center;
      justify-content: center;

      .icon-postion {
        position: absolute;
        font-size: 24px;
        margin: 18px 0px 0px 18px;
      }
    }

    .folder_name {
      font-size: 12px;
      color: #666;
      width: 90%;
      overflow: hidden;
      text-overflow: ellipsis;
      white-space: nowrap;
      text-align: center;
      padding-bottom: 8px;
      display: flex;
      justify-content: center;
      align-items: center;
      margin-left: 16px;
    }
  }
}

.mask {
  position: absolute;
  top: 0;
  left: 0;
  width: 100%;
  height: 100%;
  background-color: rgba(0, 0, 0, 0.3);
  z-index: 9999;
  border-radius: 8px;
}

:deep(.model_upload) {
  height: 20px !important;
  width: 20px !important;
  border: none;
}

:deep(.ss-upload.ss-upload-select-picture-card) {
  width: 104px !important;
  height: 52px !important;
  border-bottom-left-radius: 10px !important;
  border-bottom-right-radius: 10px !important;
  border: none !important;
}

.model_upload_text {
  width: 100px;
  height: 55px;
  display: flex;
  align-items: center;
  justify-content: center;
}
:deep(.ss-upload-select-text) {
  width: 100% !important;
  height: 100% !important;
  display: flex !important;
  align-items: center !important;
  justify-content: center !important;
  :hover {
    color: #fff !important;
    background-color: #73cff8;
    border-radius: 5px;
  }
}


  .noupload_custom_upload {
    width: 110px;
    height: 100px;
    border-radius: 10px;
    background: #f9f9f9 !important;
    border: 1px dashed #ddd;
    display: flex;
    flex-direction: column;
    justify-content: center;
    align-items: center;
    cursor: pointer;
    padding: 3px;
    .upload_top {
      height: 50%;
      width: 100%;
      display: flex;
      // font-weight: 700;
      align-items: center;
      justify-content: center;
      // border-bottom: 1px dashed #ccc;
      padding-bottom: 10px;
    }

    .upload_mater {
      width: 100%;
      height: 50%;
      color: #696969;

      // :hover {
      //   color: #fff !important;
      //   background-color: #73cff8;
      //   border-radius: 5px;
      // }
    }
  }
</style>
